<script setup lang="ts">
import TableHead from './TableHead.vue'
import ReportPerson from './ReportPerson.vue'

import useAll from './useAll'
import type { LoadListParams } from './types'
import { useStatementStore } from '@/store'
import { plus, uuid } from '@/utils'

import {
  loadEnergyConsumptionStructure,
  selectEnergyDiscountList,
} from '@/api/modules/enterpriseQuarterlyReport'

const calc = computed(() => {
  const listsValue = lists.value.map(v => v.data)
  return listsValue.map((vv) => {
    const t1 = vv.find(
      x => x.key === 'industrialProduction',
    )
    const t2 = vv.find(
      x => x.key === 'nonIndustrialProduction',
    )
    if (t1 && t2) {
      return plus(t1?.value, t2?.value)
    }
    return ''
  })
})

const summary = computed(() => {
  const obj = {
    energyName: '能源合计',
    unitOfMeasurement: '',
    code: '40',
    referenceDiscountFactor: '',
  }
  const listsValue = lists.value.map(v => v.data)
  // 折标系数
  const sss = listsValue.map((v) => {
    const target = v.find(
      vv => vv.key === 'useScalingFactor',
    )
    return target ? target.value : ''
  })
  const { statementFlattenColumns: flattenColumns }
    = storeToRefs(useStatementStore())
  const props = flattenColumns.value.map(v => v.prop)
  const listsMap = props.reduce((acc, prop) => {
    if (
      ![
        'referenceDiscountFactor',
        'useScalingFactor',
      ].includes(prop)
    ) {
      acc[prop] = listsValue.map((v) => {
        const target = v.find(vv => vv.key === prop)
        return target ? target.value : ''
      })
    }
    return acc
  }, {} as any)

  // 消费量中的“合计"
  listsMap.total = [...calc.value]
  // ①期初库存合计=能源品种×采用折标系数（累加）；
  // ②实物量合计=上列数值累加；
  // ③金额合计=上列数值累加；
  // ④消费量：工业生产消费、用于原材料、非工业生产消费、合计中运输工具消费分别=能源品种×采用折标系数（累加）
  // 合计=工业生产消费累加值+非工业生产消费累计值；
  // ⑤期末库存合计=能源品种×采用折标系数（累加）。
  const accumulate = (prop: string, withFactor?: any) => {
    const n = +listsMap[prop]
      .reduce((acc: number, v: any, i: number) => {
        acc
          += (Number.isFinite(+v) ? +v : 0)
          * (withFactor ? +sss[i]! || 1 : 1)
        return acc
      }, 0)
      .toFixed(2)
    return Number.isFinite(n) ? n : ''
  }
  const getValue = (prop: string): any => {
    if (
      [
        'beginningInventory',
        'endingInventory',
        'industrialProduction',
        'forRawMaterials',
        'nonIndustrialProduction',
        'transportationConsumption',
      ].includes(prop)
    ) {
      // 期初库存量、期末库存合计
      // 工业生产消费、用于原材料、非工业生产消费、合计中运输工具消费
      return accumulate(prop, true)
    }
    else if (
      ['physicalQuantity', 'amount'].includes(prop)
    ) {
      // 实物量、金额
      return accumulate(prop)
    }
    else if (prop === 'total') {
      return plus(
        getValue('industrialProduction'),
        getValue('nonIndustrialProduction'),
      )
    }
  }
  const data = flattenColumns.value.map((v) => {
    let editable = true
    if (Object.keys(obj).includes(v.prop)) {
      editable = false
    }
    return {
      key: v.prop,
      value:
        obj[v.prop as keyof typeof obj] || getValue(v.prop),
      editable,
    }
  })

  return {
    uuid: uuid(),
    data,
  }
})

async function request(params: LoadListParams) {
  const res = await loadEnergyConsumptionStructure(params)
  const { data, ...rest } = res
  if (!data || data.length === 0) {
    const energyDiscount: any
      = await selectEnergyDiscountList()
    return {
      data: energyDiscount.map((v: any) => ({
        energyName: v.energyName || '',
        unitOfMeasurement: v.unitOfMeasurement,
        useScalingFactor: Math.min(
          ...(v.referenceDiscountFactor || '')
            .split('-')
            .map((vv: any) => +vv),
        ),
        referenceDiscountFactor:
          v.referenceDiscountFactor || '',
        code: v.code,
      })),
    }
  }

  const findIndex = data.findIndex(
    (v: any) =>
      v.energyName === '能源合计' || v.code === '40',
  )
  if (findIndex > -1) {
    data.splice(findIndex, 1)
  }
  return { data, ...rest }
}

const {
  columns,
  title,
  lists,
  informant,
  clickCallback,
  loadPrevList,

  report,
  saveStage,
  exportFile,
} = useAll(request, {
  transfer(
    data: any,
    {
      statementFlattenColumns: flattenColumns,
    },
  ) {
    const props = flattenColumns.map(v => v.prop)
    return data.map((v: any) => {
      return {
        uuid: uuid(),
        informant: {
          personInCharge: v.personInCharge,
          informer: v.informer,
          telephone: v.telephone,
          fillInDate: v.fillInDate,
        },
        data: props.map((vv) => {
          const editable = ![
            'energyName',
            'unitOfMeasurement',
            'code',
            'total',
            'referenceDiscountFactor',
          ].includes(vv)
          return {
            key: vv,
            value: String(v[vv] || ''),
            editable,
            calculable: vv === 'total',
          }
        }),
      }
    })
  },
  getCalc(row, prop, value) {
    if (prop === 'total') {
      return calc.value[row]
    }
    return value
  },
  assignExtraData(params, { data, state, illustrate }) {
    const item = data[0] || {}
    params.list.push({
      ...item,
      ...summary?.value?.data.reduce((acc, v) => {
        acc[v.key] = String(v.value || '')
        return acc
      }, {} as any),
      state,
      illustrate,
    })
  },
})
</script>

<template>
  <div
    class="height-100 statement-table position-relative overflow-hidden"
  >
    <slot
      name="title"
      :title="title"
      :report="report"
      :load-prev-list="loadPrevList"
      :save-stage="saveStage"
      :export-file="exportFile"
    >
      <h2 class="table-title">
        {{ title }}
      </h2>
    </slot>
    <div class="report-table-head">
      <table class="report-table">
        <TableHead
          :columns="columns"
          show-line-number
        />
      </table>
    </div>
    <ElScrollbar
      class="bg-color"
      style="height: calc(100% - 150px)"
      wrap-style="overflow-x: hidden;"
    >
      <table class="report-table">
        <tbody ref="tbody">
          <tr v-for="(item, i) in lists" :key="item.uuid">
            <th class="readonly width-40px line-number">
              {{ i + 1 }}
            </th>
            <td
              v-for="(d, index) in item.data"
              :key="item.uuid + index"
              :class="{ 'is-calculable': d.calculable }"
            >
              <div v-if="!d.editable" class="span-cell">
                {{ d.calculable ? calc[i] : d.value }}
              </div>
              <div v-else class="input-cell">
                <input
                  v-model="d.value"
                  type="text"
                  @click="clickCallback"
                >
              </div>
            </td>
          </tr>
          <tr class="readonly">
            <th class="readonly width-40px line-number">
              {{ lists.length + 1 }}
            </th>
            <td
              v-for="(item, index) in summary.data"
              :key="summary.uuid + index"
            >
              <div class="span-cell">
                {{ item.value }}
              </div>
            </td>
          </tr>
        </tbody>
      </table>
      <div class="fill-description">
        <ReportPerson v-model="informant" />
        <p>说明：</p>
        <p>1．主要逻辑审核关系：</p>
        <p class="padding-horizontal">
          (1) 消费合计=工业生产消费+非工业生产消费。
        </p>
        <p class="padding-horizontal">
          (2) 工业生产消费≥用于原材料。
        </p>
        <p class="padding-horizontal">
          (3) 消费合计≥运输工具消费。
        </p>
        <p>
          2．企业只填写本企业消耗的有关能源品种数值。如本表未包括企业消耗的能源品种，企业应根据统计部门要求归并入相应能源品种内。
        </p>
        <p>
          3．能源合计=∑某种能源×某种能源折标准煤系数（不重复计算“其中”项）。
        </p>
        <p>4．综合能源消费量的计算方法：</p>
        <p class="padding-horizontal">
          (1)非能源加工转换企业：综合能源消费量=工业生产消费的能源折标量合计-回收利用折标量合计（表1-2-1中第13列）。
        </p>
        <p class="padding-horizontal">
          (2)能源加工转换企业：综合能源消费量=工业生产消费的能源折标量合计-能源加工转换产出折标量合计（表1-2-1中第12列）-回收利用折标量合计（表1-2-1中第13列）。
        </p>
      </div>
    </ElScrollbar>
  </div>
</template>
